package com.lxc.trigger.http;

import com.lxc.domain.docker.model.aggregates.NginxConfig;
import com.lxc.domain.docker.model.entity.LocationEntity;
import com.lxc.domain.docker.model.entity.UpstreamEntity;
import com.lxc.domain.docker.service.ILoadBalancingService;
import com.lxc.domain.manage.model.aggregates.ApplicationSystemRichInfo;
import com.lxc.domain.manage.model.entity.GatewayServerDetailEntity;
import com.lxc.domain.manage.model.entity.GatewayServerEntity;
import com.lxc.domain.manage.service.IConfigManageService;
import com.lxc.domain.register.service.IMessageService;
import com.lxc.types.common.Result;
import com.lxc.types.enums.ResponseCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author lxc18
 * @date 2024/12/14 21:08
 * @description GatewayConfigManageController
 */

@RestController
@RequestMapping("/wg/admin/config")

public class GatewayConfigManageController {
    private Logger logger = LoggerFactory.getLogger(GatewayConfigManageController.class);

    @Resource
    private IConfigManageService configManageService;
    @Resource
    private IMessageService messageService;
    @Resource
    private ILoadBalancingService loadBalancingService;
    @GetMapping(value = "queryServerConfig", produces = "application/json;charset=utf-8")
    public Result<List<GatewayServerEntity>> queryServerConfig() {
        try {
            logger.info("查询网关服务配置项信息");
            List<GatewayServerEntity> gatewayServerEntities = configManageService.queryGatewayServerList();
            return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), gatewayServerEntities);
        } catch (Exception e) {
            logger.error("查询网关服务配置项信息异常", e);
            return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), null);
        }
    }

    /**
     * 注册网关服务节点
     *
     * @param groupId        分组标识
     * @param gatewayId      网关标识
     * @param gatewayName    网关名称
     * @param gatewayAddress 网关地址
     * @return 注册状态
     */
    @PostMapping(value = "registerGateway")
    public Result<Boolean> registerGatewayServerNode(@RequestParam String groupId, @RequestParam String gatewayId, @RequestParam String gatewayName, @RequestParam String gatewayAddress) {
        try {
            logger.info("注册网关服务节点 gatewayId：{} gatewayName：{} gatewayAddress：{}", gatewayId, gatewayName, gatewayAddress);
            boolean done = configManageService.registerGatewayServerNode(groupId, gatewayId, gatewayName, gatewayAddress);

            //获取所有的groupId,gatewayId,gatewayAddress
            List<GatewayServerDetailEntity> detailEntities = configManageService.queryGatewayServerDetailList();
            // 组装Nginx网关刷新配置信息
            Map<String, List<GatewayServerDetailEntity>> gatewayServerDetailMap = detailEntities.stream()
                    .collect(Collectors.groupingBy(GatewayServerDetailEntity::getGroupId));
            Set<String> uniqueGroupIdList = gatewayServerDetailMap.keySet();
            // Location 信息
            List<LocationEntity> locationList = new ArrayList<>();
            for (String name : uniqueGroupIdList) {
                // location /api01/ {
                //     rewrite ^/api01/(.*)$ /$1 break;
                //     proxy_pass http://api01;
                // }
                locationList.add(new LocationEntity("/" + name + "/", "rewrite ^/" + name + "/(.*)$ /$1 break;\n\t\t\tproxy_pass http://" + name + ";\n"));
//                locationList.add(new LocationEntity("/" + name + "/", "http://" + name + ";"));
            }
            //Upstream 信息
            List<UpstreamEntity> upstreamList = new ArrayList<>();
            for (String name : uniqueGroupIdList) {
                // upstream api01 {
                //     least_conn;
                //     server 172.20.10.12:9001;
                //     #server 172.20.10.12:9002;
                // }
                List<String> servers = gatewayServerDetailMap.get(name).stream()
                        .map(GatewayServerDetailEntity::getGatewayAddress)
                        .collect(Collectors.toList());
                upstreamList.add(new UpstreamEntity(name, "least_conn;", servers));
            }
            //刷新Nginx配置
            loadBalancingService.updateNginxConfig(new NginxConfig(upstreamList, locationList));

            return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), done);
        } catch (Exception e) {
            logger.error("注册网关服务节点异常", e);
            return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), false);
        }
    }

    /**
     * TODO 开发完成续应用注册后，开发这部分
     */
    @PostMapping(value = "distributionGateway")
    public void distributionGatewayServerNode(@RequestParam String groupId, @RequestParam String gatewayId) {

    }
    @PostMapping(value = "queryApplicationSystemRichInfo", produces = "application/json;charset=utf-8")
    public Result<ApplicationSystemRichInfo> queryApplicationSystemRichInfo(@RequestParam String gatewayId,@RequestParam String systemId) {
        try {
            logger.info("查询分配到网关下的待注册系统信息(系统、接口、方法) gatewayId：{},systemId:{}", gatewayId,systemId);
            ApplicationSystemRichInfo applicationSystemRichInfo = configManageService.getAllInfoByGatewayId(gatewayId,systemId);
            return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), applicationSystemRichInfo);
        } catch (Exception e) {
            logger.error("查询分配到网关下的待注册系统信息(系统、接口、方法)异常 gatewayId：{}", gatewayId, e);
            return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), null);
        }
    }
    @GetMapping(value = "queryRedisConfig", produces = "application/json;charset=utf-8")
    public Result<Map<String, String>> queryRedisConfig() {
        try {
            logger.info("查询配置中心Redis配置信息");
            Map<String, String> redisConfig = messageService.queryRedisConfig();
            return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), redisConfig);
        } catch (Exception e) {
            logger.error("查询配置中心Redis配置信息失败", e);
            return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), null);
        }
    }



}
